package com.ado.bazinga.core.interceptor;

import java.lang.reflect.Method;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.transaction.jta.UserTransactionAdapter;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import com.ado.bazinga.core.annotation.AdminLoginToken;
import com.ado.bazinga.core.annotation.PassToken;
import com.ado.bazinga.core.annotation.UserLoginToken;
import com.ado.bazinga.core.dal.entity.Admin;
import com.ado.bazinga.core.dal.entity.User;
import com.ado.bazinga.core.exception.BazingaException;
import com.ado.bazinga.core.service.AdminService;
import com.ado.bazinga.core.service.UserService;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;

/**
 *@author adonais
 *@date 2020年3月20日
 *@description AuthenticationInterceptor.java 拦截器验证token
 **/
public class AuthenticationInterceptor implements HandlerInterceptor{

	@Autowired
	@Qualifier(value = "adminService")
	private AdminService adminService ;
	@Autowired
	@Qualifier(value = "userService")
	private UserService userService ;

	@Override
	public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
			throws Exception {
		String token = request.getHeader("user_token");
		String adminToken = request.getHeader("admin_token");
		
		//		Cookie cookie =new C
		//如果不是映射到方法上直接通过
		if (!(handler instanceof HandlerMethod)) {
			return true ;
		}
		HandlerMethod handlerMethod = (HandlerMethod) handler ;
		Method method = handlerMethod.getMethod() ;
		if (method.isAnnotationPresent(PassToken.class)) {
			PassToken passToken = method.getAnnotation(PassToken.class) ;
			if (passToken.required()) {
				return true ;
			}
		}
		//检查有没有需要用户权限的注解
		if ((method.isAnnotationPresent(UserLoginToken.class)) || (method.isAnnotationPresent(AdminLoginToken.class))) {
			if (method.getAnnotation(AdminLoginToken.class) != null) {
				AdminLoginToken adminLoginToken = method.getAnnotation(AdminLoginToken.class);
				if (adminLoginToken.required()) {
					if (StringUtils.isEmpty(adminToken)) {
						response.setStatus(401);
						response.setCharacterEncoding("utf-8");
						response.setContentType("application/json; charset=utf-8");
						return false;
					}
					String adminId = null ;
					try {
						adminId = JWT.decode(adminToken).getAudience().get(0);
					}catch (JWTDecodeException e) {
						response.setStatus(401);
						response.setCharacterEncoding("utf-8");
						response.setContentType("application/json; charset=utf-8");
						return false;
					}
					Admin admin = adminService.findById(adminId) ; 
					if (admin == null) {
						throw new BazingaException("用户不存在，请重新登录");
					}
					JWTVerifier admin_jwtVerifier = JWT.require(Algorithm.HMAC256(admin.getPassword())).build();
					try {
						admin_jwtVerifier.verify(adminToken);
					}catch (JWTVerificationException e) {
						response.setStatus(401);
						response.setCharacterEncoding("utf-8");
						response.setContentType("application/json; charset=utf-8");
						return false ;
					}
					return true ;
				}
			}
			if (method.getAnnotation(UserLoginToken.class) != null) {
				UserLoginToken userLoginToken = method.getAnnotation(UserLoginToken.class);
				if (userLoginToken.required()) {
					//执行认证
					if (StringUtils.isEmpty(token)) {
						response.setStatus(401);
						response.setCharacterEncoding("utf-8");
						response.setContentType("application/json; charset=utf-8");
						return false ;
					}
					//获取token中的user id
					String userId = null;
					try {
						if (token != null) {
							userId = JWT.decode(token).getAudience().get(0);
						}
					}catch (JWTDecodeException e) {
						response.setStatus(401);
						response.setCharacterEncoding("utf-8");
						response.setContentType("application/json; charset=utf-8");
						return false ;
					}
					User user = new User() ;
					if (StringUtils.isNotEmpty(userId)) {
						user = userService.findUserById(Integer.valueOf(userId));
					}
					if (user == null) {
						response.setStatus(401);
						response.setCharacterEncoding("utf-8");
						response.setContentType("application/json; charset=utf-8");
						return false ;
					}
					//验证token
					if (StringUtils.isNotEmpty(user.getPassword())) {
						JWTVerifier user_jwtVerifier = JWT.require(Algorithm.HMAC256(user.getPassword())).build() ;
						try {
							user_jwtVerifier.verify(token);
						}catch (JWTVerificationException e) {
							response.setStatus(401);
							response.setCharacterEncoding("utf-8");
							response.setContentType("application/json; charset=utf-8");
							return false ;
						}
					}
					return true ;
				}
			}
		}
		return true;
	}

	@Override
	public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler,
			ModelAndView modelAndView) throws Exception {
		HandlerInterceptor.super.postHandle(request, response, handler, modelAndView);
	}

	@Override
	public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex)
			throws Exception {
		HandlerInterceptor.super.afterCompletion(request, response, handler, ex);
	}



}
